<template>
  <div class="image-flipper">
    <input type="file" @change="onFileChange" accept="image/*" />
    <br /><br />
    <canvas ref="canvasRef" width="500" height="500"></canvas>
    <div class="controls">
      <button @click="flip('horizontal')">水平翻转</button>
      <button @click="flip('vertical')">垂直翻转</button>
      <button @click="reset">还原</button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'

const canvasRef = ref<HTMLCanvasElement | null>(null)
const ctx = ref<CanvasRenderingContext2D | null>(null)
const img = new Image()
let originalImageData: ImageData | null = null

onMounted(() => {
  if (canvasRef.value) {
    ctx.value = canvasRef.value.getContext('2d')
  }
})

const onFileChange = (e: Event) => {
  const target = e.target as HTMLInputElement
  const file = target.files?.[0]
  if (!file || !ctx.value || !canvasRef.value) return

  const reader = new FileReader()
  reader.onload = (evt) => {
    if (!evt.target?.result) return
    img.onload = () => {
      canvasRef.value!.width = img.width
      canvasRef.value!.height = img.height
      ctx.value!.clearRect(0, 0, img.width, img.height)
      ctx.value!.drawImage(img, 0, 0)
      originalImageData = ctx.value!.getImageData(0, 0, img.width, img.height)
    }
    img.src = evt.target.result as string
  }
  reader.readAsDataURL(file)
}

const flip = (type: 'horizontal' | 'vertical') => {
  if (!ctx.value || !canvasRef.value) return

  ctx.value.clearRect(0, 0, canvasRef.value.width, canvasRef.value.height)
  ctx.value.save()

  if (type === 'horizontal') {
    ctx.value.translate(canvasRef.value.width, 0)
    ctx.value.scale(-1, 1)
  } else if (type === 'vertical') {
    ctx.value.translate(0, canvasRef.value.height)
    ctx.value.scale(1, -1)
  }

  ctx.value.drawImage(img, 0, 0)
  ctx.value.restore()
}

const reset = () => {
  if (ctx.value && originalImageData) {
    ctx.value.putImageData(originalImageData, 0, 0)
  }
}
</script>

<style scoped>
.image-flipper {
  padding: 20px;
}
canvas {
  border: 1px solid #ccc;
  max-width: 100%;
}
.controls {
  margin-top: 10px;
}
button {
  margin-right: 10px;
}
</style>